home *** CD-ROM | disk | FTP | other *** search
- /*
- * Setting Up StandardFile
- *
- * This snippet demonstrates how to make Standard File
- * select an initial file under both System 6 and System 7.
- * (In this example, the System file will be selected.)
- *
- * "An exhilirating snippet"
- * - Nitin Ganatra
- *
- * Greg Robbins August 1993
- *
- * Changes:
- * =======
- * • sfScript is reset in the System 7 DialogHook (below) to work
- * around a gotcha in Standard File that's incorrectly documented in
- * a New Inside Macintosh: Files sample. See the DialogHook() function
- * for details.
- *
- *
- * • Compatible with the Universal Interfaces.
- *
- * Nitin Ganatra, 2/94
- *
- */
-
- #include <QuickDraw.h>
- #include <StandardFile.h>
- #include <Fonts.h>
- #include <Menus.h>
- #include <Dialogs.h>
- #include <Events.h>
- #include <GestaltEqu.h>
- #include <TextEdit.h>
- #include <Errors.h>
- #include <OSEvents.h>
- #include <Folders.h>
- #include <Memory.h>
- #include <Script.h>
- #include <LowMem.h>
-
- #ifdef __powerc
- QDGlobals qd;
- #endif
-
- // prototypes
- pascal short DialogHook(short, DialogPtr , void *);
- pascal short OldDlgHook(short, DialogPtr);
- OSErr GetSystemFileSpec(FSSpecPtr);
-
- // global struct for System 7 Std File dialog hook
- typedef struct {
- StandardFileReply *theSFR;
- FSSpec *itemSpec;
- } HookRecord, *HookRecordPtr;
-
- // globals for System 6 Std File stuff
- StringPtr gSelectFileName;
- short gSelectFileCounter;
-
-
-
-
- void main(void)
- {
- Point dialogPt;
- SFTypeList mySFTypeList;
- StandardFileReply mySFR;
- SFReply oldSFR;
- long procID;
- FSSpec systemSpec;
- HookRecord hookRec;
- Boolean hasNewStdFileCallsFlag;
- long gestResponse;
-
- OSErr retCode;
- DlgHookYDUPP myDlgHookUPP;
-
-
- // initialize the toolbox
- InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus();
- TEInit(); InitDialogs(nil); InitCursor(); FlushEvents(everyEvent,0);
-
- // determine if the System 7 std file calls are available
- retCode = Gestalt(gestaltStandardFileAttr, &gestResponse);
- if (retCode == noErr && ((gestResponse >> gestaltStandardFile58) & 1) != 0)
- hasNewStdFileCallsFlag = true;
- else
- hasNewStdFileCallsFlag = false;
-
- SetPt(&dialogPt, -1, -1);
-
- // get the FSSpec of the system file
- retCode = GetSystemFileSpec(&systemSpec);
- if (retCode != noErr) DebugStr((StringPtr)"\p GetSystemFileSpec failed");
-
- if (hasNewStdFileCallsFlag) {
-
- // System 7 method
-
- // point my hook data record at the reply record and at
- // the file spec for the system file
-
- hookRec.itemSpec = &systemSpec;
- hookRec.theSFR = &mySFR;
-
-
- // Set up the universal proc pointer to your hook routine with this
- // macro defined in StandardFile.h. **NOTE** This is different
- // from the macro used for System 6 dialog hooks, and you should get
- // a compiler error if you try to use the wrong UPP with the wrong call.
- myDlgHookUPP = NewDlgHookYDProc(DialogHook);
-
- // call Std File
- CustomGetFile(nil, -1, mySFTypeList, &mySFR, 0, dialogPt, myDlgHookUPP,
- nil, nil, nil, &hookRec);
-
- // Dispose of the routine descriptor, since they do allocate memory..
- DisposeRoutineDescriptor(myDlgHookUPP);
-
-
- }
-
- else {
- // System 6 method
-
- // stuff low memory to display the proper initial directory;
- // see Inside Mac:Files 3-31
-
- DlgHookUPP myOldDlgHookUPP;
-
- // Throw out your SysEqu.h file and start using the low memory
- // accessor functions provided in LowMem.h.
- LMSetSFSaveDisk(-systemSpec.vRefNum);
- LMSetCurDirStore(systemSpec.parID);
-
- // set up the string for the system file name
- gSelectFileName = systemSpec.name;
-
- // Set up the universal proc pointer to your hook routine with this
- // macro defined in StandardFile.h. **NOTE** This is different
- // from the macro used for System 7 dialog hooks, and you should get
- // a compiler error if you try to use the wrong UPP with the wrong call.
- myOldDlgHookUPP = NewDlgHookProc(OldDlgHook);
-
- // call Std File
- SFGetFile(dialogPt, nil, nil, -1, mySFTypeList, myOldDlgHookUPP, &oldSFR);
-
- // Dispose of the routine descriptor, since they do allocate memory..
- DisposeRoutineDescriptor(myOldDlgHookUPP);
-
- // store the result in a new reply record
- mySFR.sfGood = oldSFR.good;
- if (oldSFR.good) {
-
- // convert the WDRefNum and copy the name string
- retCode = GetWDInfo(oldSFR.vRefNum,
- &mySFR.sfFile.vRefNum, &mySFR.sfFile.parID, &procID);
- BlockMove(oldSFR.fName, mySFR.sfFile.name, 1 + oldSFR.fName[0]);
- }
- }
- }
-
- // this dialog hook for System 7 std file selects
- // the file specified by the hookRecord supplied as userData
-
- pascal short DialogHook(short item, DialogPtr theDialog,
- void *userData)
- {
- HookRecordPtr hookRecPtr;
-
- hookRecPtr = (HookRecordPtr) userData;
-
- // hookRecPtr->itemSpec points to the FSSpec of the item to be selected
- // hookRecPtr->theSFR points to the standard file reply record
-
- // make sure we're dealing with the proper dialog
- if (GetWRefCon(theDialog) == sfMainDialogRefCon) {
-
- // just when opening the dialog...
- if (item == sfHookFirstCall) {
-
- // make the reply record hold the spec of the specified item
- hookRecPtr->theSFR->sfFile = *hookRecPtr->itemSpec;
-
- // There’s a gotcha in Standard File when using sfHookChangeSelection.
- // Even though New Inside Macintosh: Files has a sample that doesn't set
- // the sfScript field, it should be set, or the last object in the
- // selected directory will always be selected.
- hookRecPtr->theSFR->sfScript = smSystemScript;
-
- // tell std file to change the selection to that item
- item = sfHookChangeSelection;
- }
- }
-
- return item;
- }
-
-
- // this std file dialog hook for System 6 selects the file
- // name in the global gSelectFileName
-
- pascal short OldDlgHook(short item, DialogPtr theDialog)
- {
- #pragma unused (theDialog)
-
- // the idea here is to post keydown events, one per
- // null hook-event, until the entire file name
- // has been "typed" in (remember that the event queue
- // is shorter than the maximum file name so we only post
- // one key per null event)
-
- // reset the character counter initially
-
- if (item == sfHookFirstCall)
- gSelectFileCounter = 0;
-
- // post one keyDown per null event until the string is exhausted
- // This may not be a good idea for international software since
- // different input methods may be used.
- // Instead, you may want to check the System version and temporarily
- // set the KeyScript to zero before doing these PostEvents.
- // Afterwards, set KeyScript back to its original mode.
- else if (item == sfHookNullEvent) {
- if (gSelectFileCounter < *gSelectFileName) {
- gSelectFileCounter++;
- PostEvent(keyDown, *(gSelectFileName+gSelectFileCounter));
- }
- }
-
- return item;
- }
-
-
- OSErr GetSystemFileSpec(FSSpecPtr systemSpec)
- {
- // the System folder location is returned by FindFolder (or under
- // System 6 by the compiler's FindFolder glue)
- //
- // the System file name is available in low-memory
-
- OSErr retCode;
- StringPtr systemName;
-
- systemName = LMGetSysResName(); // Get the name of the System resource file
-
- retCode = FindFolder(kOnSystemDisk, kSystemFolderType, kCreateFolder,
- &systemSpec->vRefNum, &systemSpec->parID);
- if (retCode == noErr)
- BlockMove((Ptr)systemName, systemSpec->name, systemName[0] + 1);
-
- return retCode;
- }
-